home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqtools / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-18  |  12.1 KB  |  619 lines

  1. #define    LIBQTOOLS_CORE
  2. #include "../include/libqtools.h"
  3.  
  4. char *preProcessor = 0;
  5.  
  6. /*
  7.  * debug-tools
  8.  */
  9.  
  10. #ifdef    MEM_SIZETRACK
  11. #define    FRONTWALL    0
  12. #define    BACKWALL    0
  13.  
  14. #ifdef    MEM_ANALYSE
  15. int memcounter = 0;
  16. int mempeak = 0;
  17. int memallocs = 0;
  18. int mempeakallocs = 0;
  19.  
  20. #endif
  21.  
  22. void *tmalloc(register int size)
  23. {
  24.   int *ret;
  25.  
  26.   /* use calloc instead ? */
  27.   if ((ret = (int *)malloc(size + sizeof(int) + BACKWALL + FRONTWALL))) {
  28.     /* printf("zero: alloc %lx, begin %lx, end %lx, size %d\n", ret, ret + ((sizeof(int) + FRONTWALL) / sizeof(int)), ((char *)(ret + ((sizeof(int) + FRONTWALL) / sizeof(int)))) + size, size); */
  29.     __bzero(ret + ((sizeof(int) + FRONTWALL) / sizeof(int)), size);
  30.  
  31. #ifdef    MEM_ANALYSE
  32.     memcounter += size + sizeof(int) + BACKWALL + FRONTWALL;
  33.  
  34.     memallocs++;
  35.     if (memcounter > mempeak)
  36.       mempeak = memcounter;
  37.     if (memallocs > mempeakallocs)
  38.       mempeakallocs = memallocs;
  39.     *ret++ = size;
  40. #endif
  41.     ((char *)ret) += FRONTWALL;
  42.   }
  43.   return (void *)ret;
  44. }
  45.  
  46. void tfree(register void *adr)
  47. {
  48.   if (adr) {
  49. #if defined(__amigaos__) && defined(DEBUG)
  50.     int addr = (int)adr >> 28;
  51.  
  52.     if (addr) {
  53.       eprintf("leak found for %lx\n", adr);
  54.     }
  55.     else {
  56.       int *ret = (int *)adr - (FRONTWALL / sizeof(int));
  57.  
  58. #ifdef    MEM_ANALYSE
  59.       memcounter -= *--ret - sizeof(int) - BACKWALL - FRONTWALL;
  60.  
  61.       memallocs--;
  62. #endif
  63.       free(ret);
  64.     }
  65. #else
  66.     int *ret = (int *)adr - (FRONTWALL / sizeof(int));
  67.  
  68. #ifdef    MEM_ANALYSE
  69.     memcounter -= *--ret - sizeof(int) - BACKWALL - FRONTWALL;
  70.  
  71.     memallocs--;
  72. #endif
  73.     free(ret);
  74. #endif
  75.   }
  76. }
  77.  
  78. int tsize(register void *adr)
  79. {
  80.   if (adr)
  81.     return *((int *)adr - (FRONTWALL / sizeof(int)) - sizeof(int));
  82.  
  83.   else
  84.     return 0;
  85. }
  86.  
  87. void *trealloc(register void *adr, register int newsize)
  88. {
  89.   if (adr) {
  90.     int *ret;
  91.     int oldsize = *((int *)adr - 1);
  92.  
  93.     if ((ret = (int *)tmalloc(newsize))) {
  94.       /* copy only valid bytes, leave more bytes cleared */
  95.       __memcpy(ret, adr, oldsize < newsize ? oldsize : newsize);
  96.     }
  97.  
  98.     tfree(adr);
  99.     return (void *)ret;
  100.   }
  101.   else
  102.     return tmalloc(newsize);
  103. }
  104. #endif
  105.  
  106. /*
  107.  * an interface for temporary memtracking with automatic freeing after use
  108.  */
  109.  
  110. struct memtrack {
  111.   struct memtrack *next;
  112.   int something[1];
  113. };
  114.  
  115. struct memtrack *firstmalloc = 0;
  116. struct memtrack *lastmalloc = 0;
  117.  
  118. void *kmalloc(register int size)
  119. {
  120.   struct memtrack *ret;
  121.  
  122.   if ((ret = (struct memtrack *)tmalloc(size + sizeof(struct memtrack *)))) {
  123.     if (!firstmalloc) {
  124.       firstmalloc = ret;
  125.       lastmalloc = ret;
  126.     }
  127.     else {
  128.       lastmalloc->next = ret;
  129.       lastmalloc = ret;
  130.     }
  131.   }
  132.   return (void *)&ret->something[0];
  133. }
  134.  
  135. void kfree(register void)
  136. {
  137.   if (firstmalloc) {
  138.     struct memtrack *first = firstmalloc;
  139.     struct memtrack *next;
  140.  
  141.     while (first) {
  142.       next = first->next;
  143.       tfree(first);
  144.       first = next;
  145.     }
  146.  
  147.     firstmalloc = 0;
  148.     lastmalloc = 0;
  149.   }
  150. }
  151.  
  152. char *smalloc(register char *in)
  153. {
  154.   char *string = 0;
  155.  
  156.   if (in)
  157.     if ((string = (char *)tmalloc(__strlen(in) + 1)))
  158.       __strcpy(string, in);
  159.   return string;
  160. }
  161.  
  162. /*
  163.  * message handling
  164.  */
  165.  
  166. bool verbose = FALSE;
  167. bool fatal = FALSE;
  168.  
  169. /* longjump with this on error */
  170. jmp_buf eabort;
  171.  
  172. void Error(char *error,...)
  173. {
  174.   va_list argptr;
  175.  
  176.   fprintf(stderr, "Error: ");
  177.   va_start(argptr, error);
  178.   vfprintf(stderr, error, argptr);
  179.   va_end(argptr);
  180.   fflush(stderr);
  181.   longjmp(eabort, 1);
  182. }
  183.  
  184. void eprintf(char *text,...)
  185. {
  186.   va_list argptr;
  187.  
  188.   fprintf(stderr, "Warning: ");
  189.   va_start(argptr, text);
  190.   vfprintf(stderr, text, argptr);
  191.   va_end(argptr);
  192.   fflush(stderr);
  193.   if (fatal)
  194.     longjmp(eabort, 1);
  195. }
  196.  
  197. #ifdef    VERBOSE
  198. void oprintf(char *text,...)
  199. {
  200.   if (verbose) {
  201.     va_list argptr;
  202.  
  203.     va_start(argptr, text);
  204.     vfprintf(stdout, text, argptr);
  205.     va_end(argptr);
  206.     fflush(stdout);
  207.   }
  208. }
  209. #endif
  210.  
  211. void mprintf(char *text,...)
  212. {
  213.   va_list argptr;
  214.  
  215.   va_start(argptr, text);
  216.   vfprintf(stdout, text, argptr);
  217.   va_end(argptr);
  218.   fflush(stdout);
  219. }
  220.  
  221. /*
  222.  * platform-independent progressbar (text-based)
  223.  */
  224.  
  225. void mprogress(register int max, register int current)
  226. {
  227. #ifdef VALID_ESCAPES
  228.   printf("\n\eM    - %2.2f%%", (float)(current * 100) / max);
  229.   if (current >= max)
  230.     printf("\n\eM");
  231.   fflush(stdout);
  232. #else
  233.   printf("\xD\x9B\x4B    - %2.2f%%", (float)(current * 100) / max);
  234.   if (current >= max)
  235.     printf("\xD\x9B\x4B");
  236.   fflush(stdout);
  237. #endif
  238. }
  239.  
  240. /*
  241.  * disk-tools
  242.  */
  243.  
  244. void CreatePath(register char *fileName)
  245. {
  246.   char *delAdr1 = fileName, *delAdr2 = fileName;
  247.  
  248.   while ((delAdr2 = (char *)__strchr(delAdr1, '/'))) {
  249.     *delAdr2 = '\0';
  250.     mkdir(fileName, ALLPERMS);
  251.     *delAdr2 = '/';
  252.     delAdr1 = ++delAdr2;
  253.   }
  254. }
  255.  
  256. char *GetExt(register char *Name)
  257. {
  258.   if (Name) {
  259.     char *Ext = (char *)__strrchr(Name, '.');
  260.  
  261.     if (!Ext)
  262.       return (char *)__strchr(Name, '\0');
  263.     else {
  264.       /*
  265.        * delete everything after 4 chars 
  266.        * Ext[4] = '\0';
  267.        */
  268.       return ++Ext;
  269.     }
  270.   }
  271.   else
  272.     return 0;
  273. }
  274.  
  275. void StripExt(register char *Name)
  276. {
  277.   if (Name) {
  278.     char *Ext;
  279.  
  280.     if ((Ext = (char *)__strrchr(Name, '.')))
  281.       *Ext = '\0';
  282.   }
  283. }
  284.  
  285. void ReplaceExt(register char *Name, register char *newExt)
  286. {
  287.   if (Name) {
  288.     char *Ext;
  289.  
  290.     if ((Ext = (char *)__strrchr(Name, '.'))) {
  291.       *++Ext = '\0';
  292.       __strcpy(Ext, newExt);
  293.     }
  294.     else {
  295.       __strcat(Name, ".");
  296.       __strcat(Name, newExt);
  297.     }
  298.   }
  299. }
  300.  
  301. /*
  302.  * get the file-part of a path
  303.  */
  304. char *GetFile(register char *Name)
  305. {
  306.   if (Name) {
  307.     char *Ext = (char *)__strrchr(Name, '/');
  308.  
  309.     if (!Ext)
  310.       return Name;
  311.     else {
  312.       return ++Ext;
  313.     }
  314.   }
  315.   else
  316.     return 0;
  317. }
  318.  
  319. /*
  320.  * check for valid unix-path
  321.  */
  322. void ValidateDir(register char *Name)
  323. {
  324.   short int len = __strlen(Name);
  325.  
  326.   while (Name[len] == '/')
  327.     Name[len--] = '\0';
  328. }
  329.  
  330. void *GetVoidF(register HANDLE getFile)
  331. {
  332.   void *voidData = 0;
  333.   int size;
  334.  
  335.   __lseek(getFile, 0, SEEK_END);
  336.   size = __ltell(getFile);
  337.   __lseek(getFile, 0, SEEK_SET);
  338.  
  339.   if ((voidData = (void *)tmalloc(size + 1))) {
  340.     char *byteData = (char *)voidData;
  341.  
  342.     __read(getFile, voidData, size);
  343.     byteData[size] = '\0';
  344.   }
  345.   else
  346.     eprintf(failed_memory, size, "void data");
  347.  
  348.   return voidData;
  349. }
  350.  
  351. void *GetVoid(register char *fileName)
  352. {
  353.   HANDLE getFile = __open(fileName, H_READ_BINARY);
  354.   void *voidData = 0;
  355.  
  356.   if (getFile > 0) {
  357.     voidData = GetVoidF(getFile);
  358.     __close(getFile);
  359.   }
  360.  
  361.   return voidData;
  362. }
  363.  
  364. void *GetPreProcessed(register char *fileName)
  365. {
  366.   if (preProcessor) {
  367.     char *tmpName;
  368.     void *tmpData = 0;
  369.  
  370.     if ((tmpName = tmpnam(0))) {
  371.       char *exeLine;
  372.  
  373.       if ((exeLine = (char *)tmalloc(__strlen(preProcessor) + 1 + __strlen(fileName) + 1 + __strlen(tmpName) + 1))) {
  374.     __strcpy(exeLine, preProcessor);
  375.     __strcat(exeLine, " ");
  376.     __strcat(exeLine, fileName);
  377.     __strcat(exeLine, " ");
  378.     __strcat(exeLine, tmpName);
  379.  
  380.     system(exeLine);
  381.  
  382.     tmpData = GetVoid(tmpName);
  383.     remove(tmpName);
  384.       }
  385.     }
  386.  
  387.     return tmpData;
  388.   }
  389.   else
  390.     return GetVoid(fileName);
  391. }
  392.  
  393. /*
  394.  * allocate greatest buffer for a given size that is available
  395.  * first tries with maximum memory and then tries with smaller
  396.  * buffers upto an error
  397.  */
  398. void *SmartBuffer(int len, int *clusters, int *clustersize, int *rest)
  399. {
  400.   void *buffer = 0;
  401.  
  402.   *clusters = 1;
  403.   *clustersize = len;
  404.   *rest = 0;
  405.  
  406.   if (*clustersize > 0) {
  407.     while (*clustersize > 0) {
  408.       if ((buffer = tmalloc(*clustersize))) {
  409.     break;
  410.       }
  411.       else {
  412.     *clustersize >>= 1;
  413.     *clusters <<= 1;
  414.     *rest = len % *clustersize;
  415.       }
  416.     }
  417.   }
  418.   else
  419.     buffer = (void *)tmalloc(1);
  420.  
  421.   return buffer;
  422. }
  423.  
  424. /*
  425.  * cuts bytes out of a file
  426.  * (file is REAL shorter)
  427.  * stores cuttet bytes if buffer != 0
  428.  */
  429. #ifdef    UNLIMITED
  430. bool CutOff(HANDLE procFile, int byteValue, void *buffer)
  431. {
  432.   if (byteValue && procFile) {
  433.     int begin = __ltell(procFile);
  434.     int difference;
  435.  
  436.     if (buffer) {
  437.       if (__read(procFile, buffer, byteValue) != byteValue)
  438.     return FALSE;
  439.     }
  440.  
  441.     /* cut of in steps */
  442.     __lseek(procFile, 0, SEEK_END);
  443.     difference = __lseek(procFile, 0, SEEK_CUR) - begin - byteValue;
  444.     if ((buffer = (void *)tmalloc(difference))) {
  445.       __lseek(procFile, begin + byteValue, SEEK_SET);
  446.       __read(procFile, buffer, difference);
  447.       __lseek(procFile, begin, SEEK_SET);
  448.       __write(procFile, buffer, difference);
  449.       __lseek(procFile, begin, SEEK_SET);
  450.       if (ftruncate(procFile, begin + difference) == -1)
  451.     printf("failed to truncate file to %d bytes\n", begin + difference);
  452.       free(buffer);
  453.       return TRUE;
  454.     }
  455.     else
  456.       return FALSE;
  457.   }
  458.   else
  459.     return TRUE;
  460. }
  461. #else
  462. bool CutOff(HANDLE procFile, int byteValue, void *buffer)
  463. {
  464.   if (byteValue && procFile) {
  465.     bool success;
  466.     int clusters, clustersize, rest;
  467.     int begin;
  468.     int difference;
  469.  
  470.     if (buffer)
  471.       if (__read(procFile, buffer, byteValue) != byteValue)
  472.     return FALSE;
  473.  
  474.     success = FALSE;
  475.     begin = __lseek(procFile, 0, SEEK_CUR);
  476.  
  477.     /* cut of in steps */
  478.     __lseek(procFile, 0, SEEK_END);
  479.     difference = __lseek(procFile, 0, SEEK_CUR) - begin - byteValue;
  480.  
  481.     if ((buffer = SmartBuffer(difference, &clusters, &clustersize, &rest))) {
  482.     /* copy forwards */
  483.     __lseek(procFile, begin + byteValue, SEEK_SET);
  484.     while (clusters--) {
  485.       if (__read(procFile, buffer, clustersize) != clustersize) {
  486.         break;
  487.       }
  488.       __lseek(procFile, -clustersize - byteValue, SEEK_CUR);    /* seek backward */
  489.       if (__write(procFile, buffer, clustersize) != clustersize) {
  490.         break;
  491.       }
  492.       __lseek(procFile, byteValue, SEEK_CUR);        /* seek forward */
  493.     }
  494.  
  495.     if (clusters == -1) {
  496.       if (rest) {
  497.         if (__read(procFile, buffer, rest) == rest) {
  498.           __lseek(procFile, -rest - byteValue, SEEK_CUR);    /* seek backward */
  499.           if (__write(procFile, buffer, rest) == rest)
  500.         success = TRUE;
  501.         }
  502.       }
  503.       else
  504.         success = TRUE;
  505.     }
  506.  
  507.       if (success) {
  508.     __lseek(procFile, begin, SEEK_SET);
  509.     if (ftruncate(procFile, begin + difference) == -1)
  510.       success = FALSE;
  511.       }
  512.  
  513.       tfree(buffer);
  514.     }
  515.  
  516.     return success;
  517.   }
  518.   else
  519.     return TRUE;
  520. }
  521. #endif
  522.  
  523. /*
  524.  * pastes bytes to a file
  525.  * (file is REAL longer)
  526.  * write bytes if buffer != 0
  527.  */
  528. #ifdef    UNLIMITED
  529. bool PasteIn(HANDLE procFile, int byteValue, void *buffer)
  530. {
  531.   if (byteValue && procFile) {
  532.     int begin = __ltell(procFile);
  533.     int difference;
  534.     void *bufferNew;
  535.  
  536.     if (!buffer)
  537.       buffer = (void *)PasteIn;                    /* copy something */
  538.  
  539.     /* paste in in steps */
  540.     __lseek(procFile, 0, SEEK_END);
  541.     difference = __lseek(procFile, 0, SEEK_CUR) - begin;
  542.     if ((bufferNew = (void *)tmalloc(difference)) && buffer) {
  543.       __lseek(procFile, begin, SEEK_SET);
  544.       __read(procFile, bufferNew, difference);
  545.       __lseek(procFile, begin, SEEK_SET);
  546.       __write(procFile, buffer, byteValue);
  547.       __write(procFile, bufferNew, difference);
  548.       __lseek(procFile, begin, SEEK_SET);
  549.       free(bufferNew);
  550.       return TRUE;
  551.     }
  552.     else
  553.       return FALSE;
  554.   }
  555.   else
  556.     return TRUE;
  557. }
  558. #else
  559. bool PasteIn(HANDLE procFile, int byteValue, void *buffer)
  560. {
  561.   if (byteValue && procFile) {
  562.     bool success;
  563.     int clusters, clustersize, rest, begin, difference;
  564.     void *copybuffer;
  565.  
  566.     success = FALSE;
  567.     begin = __lseek(procFile, 0, SEEK_CUR);
  568.  
  569.     /* paste in in steps */
  570.     __lseek(procFile, 0, SEEK_END);
  571.     difference = __lseek(procFile, 0, SEEK_CUR) - begin;
  572.  
  573.     if ((copybuffer = SmartBuffer(difference, &clusters, &clustersize, &rest))) {
  574.     /* copy backwards */
  575.     __lseek(procFile, 0, SEEK_END);
  576.     while (clusters--) {
  577.       __lseek(procFile, -clustersize, SEEK_CUR);
  578.       if (__read(procFile, copybuffer, clustersize) != clustersize) {
  579.         break;
  580.       }
  581.       __lseek(procFile, -clustersize + byteValue, SEEK_CUR);
  582.       if (__write(procFile, copybuffer, clustersize) != clustersize) {
  583.         break;
  584.       }
  585.     }
  586.  
  587.     if (clusters == -1) {
  588.       if (rest) {
  589.         __lseek(procFile, -rest, SEEK_CUR);
  590.         if (__read(procFile, copybuffer, rest) == rest) {
  591.           __lseek(procFile, -rest + byteValue, SEEK_CUR);
  592.           if (__write(procFile, copybuffer, rest) == rest)
  593.         success = TRUE;
  594.         }
  595.       }
  596.       else
  597.         success = TRUE;
  598.     }
  599.  
  600.       if (success) {
  601.     if (buffer) {
  602.       __lseek(procFile, begin, SEEK_SET);
  603.       if (__write(procFile, buffer, byteValue) != byteValue)
  604.         success = FALSE;
  605.     }
  606.     else
  607.       __lseek(procFile, begin + byteValue, SEEK_SET);
  608.       }
  609.  
  610.       tfree(copybuffer);
  611.     }
  612.  
  613.     return success;
  614.   }
  615.   else
  616.     return TRUE;
  617. }
  618. #endif
  619.